from . import home
from app import db
from app.home.forms import LoginForm,RegisterForm,PasswordForm,OrderForm 
from app.models import User,Goods,Orders,Cart,OrdersDetail,SuperCat, SubCat
from flask import render_template, url_for, redirect, flash, session, request,make_response
from functools import wraps
from werkzeug.security import generate_password_hash
import random
import string,time
from PIL import Image, ImageFont, ImageDraw
from io import BytesIO
from sqlalchemy.sql import exists
from flask_paginate import Pagination, get_page_args


@home.route("/")
def index():
    """
    首页
    """
    # 获取3个热门商品
    hot_goods = Goods.query.order_by(Goods.views_count.desc()).limit(3).all()
    # 获取6个新品
    new_goods = Goods.query.filter_by(is_new=1).order_by(
                    Goods.addtime.desc()
                        ).limit(6).all()
    # 获取5个打折商品
    sale_goods = Goods.query.filter_by(is_sale=1).order_by(
                    Goods.addtime.desc()
                        ).limit(6).all()

    data = [hot_goods,new_goods,sale_goods]

    # big_categories = SuperCat.query.all()
    # small_categories = SubCat.query.all()
    
    # if "user_id" in session:
    #     return render_template('home/index.html',logged_in=True,new_goods=new_goods,sale_goods=sale_goods,hot_goods=hot_goods) # 渲染模板
    # else:
    #     return render_template('home/index.html',logged_in=False,new_goods=new_goods,sale_goods=sale_goods,hot_goods=hot_goods) # 渲染模板

    return render_template('home/index.html',new_goods=new_goods,sale_goods=sale_goods,hot_goods=hot_goods) # 渲染模板


@home.context_processor
def global_data():
    """
        注册分类数据的全局上下文变量
    """
    big_categories = SuperCat.query.all()
    small_categories = SubCat.query.all()
    return dict(big_categories=big_categories, small_categories=small_categories)


# @home.route('/login/',methods = ['GET','POST'])
# def login():
#     """[summary]
    
#     [description]
    
#     Returns:
#         [type]: [description]
#     """
#     # # data = form.data
#     # print(form.data)
#     # 首先判断用户的id是否存在session
#     if 'user_id' in session:
#         return redirect(url_for('home.index'))
#     # 实例化登录的表单类，以通过表单类来获取表单数据
#     form = LoginForm()
#     # 检测表单是否提交，是前提，如果提交就获取表单数据
#     if form.validate_on_submit():
#         data = form.data
#         if session.get('image').lower() != form.verify_code.data.lower():
#             flash('验证码错了哟', 'err')
#             return render_template('home/login.html', form = form)
#         user = User.query.filter_by(username = data['username']).first()    

#         if not user:
#             flash("用户名不存在", 'err')
#             return render_template('home/login.html', form = form)

#         if not user.check_password(data['password']):
#             flash('密码错哈！', 'err')
#             return render_template ('home/login.html',form = form)

#         session['user_id']  = user.id
#         session['username'] = user.username
#         return redirect(url_for('home.index'))
#     return render_template('home/login.html', form = form)
'''
用户登录注册部分视图控制器

'''

@home.route('/login/', methods=['GET', 'POST'])
def login():
    # 首先判断用户的id是否存在session
    # if 'user_id' in session:
    #     return render_template('home/index.html')
    form = LoginForm()
    if form.validate_on_submit():
        data = form.data
        # print(data.get('password'))
        
        user = User.query.filter_by(username=data['username']).first()
        # print(user.check_password(data['password']))
        if handle_login_errors(data, user):
            return render_template('home/login.html', form=form)
        session['user_id'] = user.id
        session['username'] = user.username
        return redirect(url_for('home.index'))
    return render_template('home/login.html', form=form)


def handle_login_errors(data, user):
    '''验证登录数据
    
    '''
    if session.get('image').lower()!= data['verify_code'].lower():
        flash('验证码错了哟', 'err')
        return True
    if not user:
        flash("用户名不存在", 'err')
        return True
    if not user.check_password(data['password']):
        flash('密码错哈！', 'err')
        return True
    return False


@home.route('/register/',methods = ['GET','POST'])
def register():
    if 'user_id' in session:
        return redirect(url_for('home.index'))

    form = RegisterForm()
    if form.validate_on_submit():
        data = form.data
        # print(f"输入的密码：{data['password']}")
        password_hash = generate_password_hash(data['password'])
        # print(f"生成的哈希数：{password_hash}")
        user = User(
            username = data['username'],
            email = data['email'],
            password = password_hash,
            phone = data['phone']
            )
        try:
            db.session.add(user)
            db.session.commit()
            return redirect(url_for('home.login'))
        except Exception as e:
            # 处理可能的数据库提交错误
            flash("注册时发生错误", "err")
            db.session.rollback()
        return redirect(url_for('home.login'))

    return render_template('home/register.html',form = form)


@home.route('/logout/')
def logout():
    # form = RegisterForm()
    # data = form.data
    session.pop('user_id',None)
    session.pop('username',None)
    return redirect(url_for('home.login'))


def user_login(f):
    """
    登录装饰器
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if "user_id" not in session:
            return redirect(url_for("home.login"))
        return f(*args, **kwargs)

    return decorated_function


@home.route('/modify_password/',methods = ['GET','POST'])
@user_login
def modify_password():
    # form = RegisterForm()
    # data = form.data
    form = PasswordForm()
    if form.validate_on_submit():
        data = form.data
        # user = User.query.filter_by(username = session['username']).first()
        user = User.query.filter_by(id=session['user_id']).first()
        # print(username)
        user.password = generate_password_hash(data['password'])
        db.session.add(user)
        db.session.commit()
        return "<script>alert('密码修改成功');location.href='/';</script>"
    return render_template('home/modify_password.html',form = form)

'''
商品信息部分

'''
@home.route('/goods_list/<int:supercat_id>/')
def goods_list(supercat_id=None):
    # form = RegisterForm()
    # data = form.data
    page = request.args.get('page',1,type=int)
    page_data = Goods.query.filter_by(supercat_id=supercat_id).paginate(page=page, per_page=12)
    hot_goods = Goods.query.filter_by(supercat_id=supercat_id).order_by(Goods.views_count.desc()).limit(7).all()

    return render_template('home/goods_list.html',page_data=page_data,hot_goods=hot_goods,supercat_id=supercat_id)  


@home.route('/goods_detail/<int:id>')
def goods_detail(id):
    user_id = session.get('user_id',0)
    goods = Goods.query.get_or_404(id)

    goods.views_count +=1
    db.session.add(goods)
    db.session.commit()

    hot_goods = Goods.query.filter_by(subcat_id=goods.subcat_id).order_by(Goods.views_count.desc()).limit(5).all()
    similar_goods =  Goods.query.filter_by(subcat_id=goods.subcat_id).order_by(Goods.addtime.desc()).limit(5).all()

    return render_template('home/goods_detail.html',goods =goods,hot_goods=hot_goods,similar_goods=similar_goods,user_id=user_id)


@home.route('/search/')
def goods_search():
    
    page = request.args.get('page',1,type=int)
    keywords = request.args.get('keywords','',type=str)

    if keywords:
        page_data = Goods.query.filter(Goods.name.like("%"+keywords+"%")).order_by(Goods.addtime.desc()).paginate(page=page,per_page=12)
    else:
        # 
        return "请输入你得关键词！！！！兄各地"
    hot_goods = Goods.query.order_by(Goods.views_count.desc()).limit(7).all()

    return render_template("home/goods_search.html",page_data=page_data,keywords=keywords,hot_goods=hot_goods)




"""
购物车功能部分的视图控制器

"""

@home.route('/shopping_cart/')
@user_login
def shopping_cart():
    form = OrderForm()
    data = form.data
    # print(form.data.goods_id)
    user_id = session.get('user_id',0)
    cart = Cart.query.filter_by(user_id = int(user_id)).order_by(Cart.addtime.desc()).all()
    # print(cart)
    if cart:
        return render_template('home/shopping_cart.html',cart=cart,form=form)
    else:
        return render_template('home/shopping_cart.html',form=form)


@home.route('/cart_add/')
@user_login
def cart_add():
    # 通过request获取当前用户得userid和加购得商品id，
    
    goods_id = int(request.args.get('goods_id'))
    number = int(request.args.get('number'))
    user_id = session.get('user_id', 0)

    goods = Goods.query.get(goods_id)   #查询商品信息
    # 这里其实还需要更多得判断，比方说线程，确保库存和一致性
    if number > goods.stock:
        return '库存不足'
        # print('库存不足')
        #判断当前用户选择得当前商品是否已经存在购物车了，如果存在这将数量添加上去 
    cart_item = Cart.query.filter_by(user_id=user_id, goods_id=goods_id).first()
    if cart_item:
        cart_item.number += number

    else:
        # 如果不存在，则将获取得信息全部传递给购物车模型入库
        cart_item = Cart(user_id=user_id, goods_id=goods_id, number=number)
    db.session.add(cart_item)
    db.session.commit()

    # return 
    # print('能打印出来就是前端成功调用')
    return redirect(url_for('home.shopping_cart'))   


@home.route('/modify_cart', methods=['GET','POST'])
@user_login
def modify_cart():
    cart_id = int(request.form['cart_id'])
    user_id = session.get('user_id', 0)
    new_number = int(request.form['new_number'])

    cart_item = Cart.query.get(cart_id)
    
    if cart_item.user_id!= user_id:
    
        return '无权修改此购物车项'
    
    goods = Goods.query.get(cart_item.goods_id)
    if new_number > goods.stock:
        return '库存不足'

    cart_item.number = new_number
    db.session.commit()

    return redirect(url_for('shopping_cart'))


@home.route('/delete_from_cart/<int:cart_id>')
@user_login
def delete_from_cart(cart_id):
    cart_item = Cart.query.get(cart_id)

    if cart_item.user_id!= user_id:
        return '无权删除此购物车项'
    db.session.delete(cart_item)
    db.session.commit()

    return redirect(url_for('shopping_cart'))


@home.route('/cart_clear/')
@user_login
def cart_clear():
    '''清空购物车'''
    user_id = session.get('user_id',0)
    try:
        Cart.query.filter_by(user_id=user_id).update({'user_id': 0})
        db.session.commit()
    except Exception as e:
        db.session.rollback()  # 出现错误时回滚
        flash(f"清空购物车错误！: {e}", 'error')

    return redirect(url_for('home.shopping_cart'))



@home.route('/cart_order',methods = ['GET','POST'])
@user_login
def cart_order():
    if request.method == 'POST':
        #统计购买商品得总数量，每种商品再购物车页面就应该显示有

        user_id = session.get('user_id', 0)                          # 获取用户id
        selected_goods_ids = request.form.getlist('selected_goods')  # 获取已经被选中得商品id    
        total_amount = 0                                             # 声明商品总价变量初始值0
        all_cart_items = []                                          # 用于保存查询到的所有购物车项，避免重复查询

        for goods_id in selected_goods_ids:                          # 遍历用户选择的商品 ID
            cart_items = Cart.query.filter_by(user_id=user_id, goods_id=goods_id).first()  # 获取用户选中得商品
            
            if not cart_items:                                   # 判断商品有没有               
                return "未添加到购物车1"

            all_cart_items.append(cart_items)                    # 将所有商品放入列表
            goods = Goods.query.get(cart_items.goods_id)         # 获取选择了得商品详细信息        
            
            if not (goods and goods.current_price and goods.stock>=cart_items.number):                    # 判断商品信息
                return "商品库存就那么多！你少买点嘛！！！错误2"

            total_amount += goods.current_price * cart_items.number  #计算选得商品得总价格
        
        #封装订单信息到订单对象        
        order_num = int(time.time())
        orders = Orders(
            order_num = order_num,
            user_id=user_id,
            recevie_name= request.form.get('recevie_name'),
            recevie_tel = request.form.get('recevie_tel'),
            recevie_address = request.form.get('recevie_address'),
            remark = request.form.get('remark'),
            total_amount = total_amount
        )
        #尝试入库
        # try:
        db.session.add(orders)
        db.session.flush()
        #     db.session.commit() 
        # except Exception as e:
        #     db.session.rollback()
        #     flash('订单生成失败，请稍后再试', 'err') 
            
        for cart_item in all_cart_items:
            order_detail = OrdersDetail(
                order_id=orders.id,
                goods_id=cart_item.goods_id,
                number=cart_item.number,
            )
# 首先创建了一个订单对象 orders，并设置了一些必要的属性，如用户 ID（user_id）、
# 总价（total_amount）以及订单状态（status）等。
# 然后将这个订单对象添加到数据库会话（db.session.add(orders)）中。
# 接着执行 db.session.flush() 操作，
# 这一步的作用是将当前会话中的更改（这里就是添加订单对象这件事）发送到数据库，但并不立即提交这些更改。
# 这样做的好处是，数据库会为这个新添加的订单对象分配一个唯一的 ID（也就是 orders.id），
# 并且这个 ID 可以在当前会话中被获取到，即使此时整个会话还没有最终提交。
            db.session.add(order_detail)
            goods = Goods.query.get(cart_item.goods_id)
            
            goods.stock -= cart_item.number
            # print(goods.stock,'看看库存好像没动样')
            # db.session.flush()
                #删除用户已经选择了生成订单得购物车里面得商品
            Cart.query.filter_by(user_id=user_id, goods_id=goods_id).update({'user_id': 0})
                 
            # 提交整个事务，包括订单记录和订单详情记录的插入以及购物车记录的删除
        db.session.commit()  

    return redirect(url_for('home.index'))


@home.route('/order_list/',methods = ['GET','POST'])
@user_login
def order_list():
    user_id = session.get('user_id',0)

    # 设置默认的页码和每页显示数量（可根据需要调整）
    default_page = 1
    default_per_page = 2

    # 获取当前页码和每页显示数量
    page, per_page, offset = get_page_args(
        page_parameter='page',
        per_page_parameter='per_page',
        page_default=default_page,
        per_page_default=default_per_page
    )

    # 检查是否有从前端分页链接传递过来的新页码参数
    new_page = request.args.get('page')
    if new_page:
        page = int(new_page)

    # 根据更新后的页码重新计算偏移量
    offset = (page - 1) * per_page
    # default_page = 1
    # default_per_page = 2
    # # 获取当前页码和每页显示的数量
    # page, per_page, offset = get_page_args(page_parameter='page', per_page_parameter='per_page')
    # # 查询符合条件的订单总数
    total = Orders.query.filter(Orders.user_id == user_id).count()

    orders = OrdersDetail.query.join(Orders).filter(Orders.user_id==user_id).order_by(Orders.addtime.desc()).limit(per_page).offset(offset).all()
    # 创建分页对象
    pagination = Pagination(page=page, per_page=per_page, total=total)
    # print(f"pagination对象中的下一页页码值: {pagination.next_num}")
    
    return render_template('home/order_list.html',orders = orders,pagination=pagination)























































def rndColor():
    '''随机颜色'''
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

def gene_text():
    '''生成4位验证码'''
    return ''.join(random.sample(string.ascii_letters+string.digits, 4))

def draw_lines(draw, num, width, height):
    '''划线'''
    for num in range(num):
        x1 = random.randint(0, width / 2)
        y1 = random.randint(0, height / 2)
        x2 = random.randint(0, width)
        y2 = random.randint(height / 2, height)
        draw.line(((x1, y1), (x2, y2)), fill='black', width=1)

def get_verify_code():
    '''生成验证码图形'''
    code = gene_text()
    # 图片大小120×50
    width, height = 120, 50
    # 新图片对象
    im = Image.new('RGB',(width, height),'white')
    # 字体
    font = ImageFont.truetype('app/static/fonts/arial.ttf', 40)
    # draw对象
    draw = ImageDraw.Draw(im)
    # 绘制字符串
    for item in range(4):
        draw.text((5+random.randint(-3,3)+23*item, 5+random.randint(-3,3)),
                  text=code[item], fill=rndColor(),font=font )
    return im, code


@home.route('/code')
def get_code():
    image, code = get_verify_code()
    # 图片以二进制形式写入
    buf = BytesIO()
    image.save(buf, 'jpeg')
    buf_str = buf.getvalue()
    # 把buf_str作为response返回前端，并设置首部字段
    response = make_response(buf_str)
    response.headers['Content-Type'] = 'image/gif'
    # 将验证码字符串储存在session中
    session['image'] = code
    return response